/*
 * Copyright (c) 2008, Spagettikod | Stockholm
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of the Spagettikod | Stockholm nor the names of its
 *     contributors may be used to endorse or promote products derived from
 *     this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.spagettikod.t437.dialog;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Hashtable;

import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.spagettikod.SystemUtil;
import com.spagettikod.t437.T437;
import com.spagettikod.t437.simpledb.SimpleDBAttribute;
import com.spagettikod.t437.simpledb.SimpleDBDomain;
import com.spagettikod.t437.simpledb.SimpleDBItem;

public class ExportProgress extends JDialog {
	/**
	 * 
	 */
	private static final long serialVersionUID = -2616532601700615562L;

	private static final Log log = LogFactory.getLog(ExportProgress.class);

	private JProgressBar progress;

	private File outputFile;

	public ExportProgress(SimpleDBDomain domain, File f) {
		super(T437.getApplicationFrame(), true);

		outputFile = f;

		this.setTitle("Exporting...");

		JPanel rootPanel = new JPanel();
		rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.Y_AXIS));

		progress = new JProgressBar(0, 200);
		progress.setValue(0);
		progress.setStringPainted(true);
		rootPanel.add(progress);

		getContentPane().add(rootPanel);

		setResizable(false);
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

		pack();
		setLocation(SystemUtil.calculateCenterLocation(T437
				.getApplicationFrame(), this));

		final SimpleDBDomain d = domain;

		Runnable job = new Runnable() {
			public void run() {
				export(d);
			}
		};
		new Thread(job).start();

		setVisible(true);
	}

	private void export(SimpleDBDomain domain) {
		PrintWriter pw;
		try {
			pw = new PrintWriter(outputFile);
		} catch (FileNotFoundException e) {
			T437.displayErrorMessage("Export error",
					"Could not open output file " + outputFile);
			return;
		}
		if (log.isDebugEnabled()) {
			log.debug("Exporting domain: " + domain.getName());
		}
		domain.fetchData();
		Hashtable<String, Integer> headingCount = new Hashtable<String, Integer>();
		StringBuilder builder;

		// Count number of attributes per item
		int numPerPercent;
		if (domain.getItemCount() < 100) {
			numPerPercent = 1;
		} else {
			numPerPercent = domain.getItemCount() / 100;
		}

		for (SimpleDBItem item : domain.getItems()) {
			int i = 0;
			builder = new StringBuilder();
			for (SimpleDBAttribute attr : item.getAttributes()) {
				if (headingCount.get(attr.getName()) == null
						|| headingCount.get(attr.getName()) < attr
								.countValues()) {
					headingCount.put(attr.getName(), attr.countValues());
				}
			}
			if (++i == numPerPercent) {
				i = 0;
				advanceProgressBar();
			}
		}

		builder = new StringBuilder();
		builder.append("\"");
		builder.append("Item Name");
		builder.append("\",");
		for (String attrName : domain.getAttributeNames()) {
			for (int i = 0; i < headingCount.get(attrName); i++) {
				builder.append("\"");
				builder.append(attrName);
				builder.append("\",");
			}
		}
		String heading = builder.toString();
		heading = heading.substring(0, heading.length() - 1);
		pw.println(heading);

		for (SimpleDBItem item : domain.getItems()) {
			int itemCounter = 0;
			builder = new StringBuilder();
			builder.append("\"");
			builder.append(item.getKey());
			builder.append("\",");
			for (String attrName : domain.getAttributeNames()) {
				for (int i = 0; i < headingCount.get(attrName); i++) {
					builder.append("\"");
					if (item.getAttribute(attrName) != null
							&& item.getAttribute(attrName).countValues() > i) {
						builder.append(item.getAttribute(attrName).getValue(i));
					}
					builder.append("\",");
				}
			}
			String row = builder.toString();
			row = row.substring(0, row.length() - 1);
			pw.println(row);
			if (++itemCounter == numPerPercent) {
				itemCounter = 0;
				advanceProgressBar();
			}
		}
		pw.flush();
		pw.close();
		exportDone();
	}

	private void advanceProgressBar() {
		progress.setValue(progress.getValue() + 1);
	}

	private void exportDone() {
		setVisible(false);
		dispose();
	}
}
